from .common import *

'''
    功能还不完善，需要修改，存在太多的 BUG
'''

class OrderPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY)

        self._init_data()
        self._init_UI()
        self._init_listener()

    def _init_data(self):
        '''初始化必要数据'''
        self.process = None

    def _init_UI(self):
        '''初始化页面布局'''
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.SetBackgroundColour(CON_COLOR_MAIN)

        self.panel = wx.Panel(self, wx.ID_ANY)
        self.panelSizer = wx.BoxSizer(wx.VERTICAL)
        self.panel.SetSizer(self.panelSizer)
        self.panelSizer.SetSizeHints(self.panel)
        sizer.Add(self.panel, 1, wx.EXPAND)

        '''
            滚动面板
        '''
        self.scollPanel = scrolledpanel.ScrolledPanel(self.panel, -1)
        self.scollPanel.SetupScrolling()
        self.scollPanelSizer = wx.BoxSizer(wx.VERTICAL)
        self.scollPanel.SetSizer(self.scollPanelSizer)
        self.panelSizer.Add(self.scollPanel, 3, wx.EXPAND | wx.ALL, 2)

        '''
            弹性布局
        '''
        self.flexGridSizer = wx.FlexGridSizer(cols=4, hgap=1, vgap=1)
        self.scollPanelSizer.Add(self.flexGridSizer, 0, wx.EXPAND | wx.ALL, 1)
        self.flexGridSizer.AddGrowableCol(0)

        self.textCtrlInputOrder = wx.TextCtrl(self.scollPanel, -1, value='', style=wx.TE_PROCESS_ENTER)
        self.btnExec = buttons.GenButton(self.scollPanel, -1, label='执行')
        self.btnSendData = buttons.GenButton(self.scollPanel, -1, label='发送数据流')
        self.btnStop = buttons.GenButton(self.scollPanel, -1, label='终止数据流')
        self._set_btn_color([self.btnExec, self.btnSendData, self.btnStop])

        self.flexGridSizer.Add(self.textCtrlInputOrder, 0, wx.EXPAND)
        self.flexGridSizer.Add(self.btnExec, 0, wx.EXPAND)
        self.flexGridSizer.Add(self.btnSendData, 0, wx.EXPAND)
        self.flexGridSizer.Add(self.btnStop, 0, wx.EXPAND)

        '''
            命令显示面板
        '''
        self.infoOrderResult = wx.TextCtrl(self.scollPanel, -1, value='', style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.infoOrderResult.SetBackgroundColour('#1e1e1e')
        self.infoOrderResult.SetForegroundColour(wx.WHITE)
        self.scollPanelSizer.Add(self.infoOrderResult, 1, wx.EXPAND | wx.ALL, 1)

    def _set_btn_color(self, obj):
        '''
            按钮颜色变更，黑底，白字
        '''
        if isinstance(obj, list):
            for o in obj:
                o.SetBackgroundColour(CON_COLOR_MAIN)
                o.SetForegroundColour(CON_COLOR_WHITE)
        else:
            obj.SetBackgroundColour(CON_COLOR_MAIN)
            obj.SetForegroundColour(CON_COLOR_WHITE)

    def _init_listener(self):
        '''初始化监听'''
        self.Bind(wx.EVT_TEXT_ENTER, self.onEnterInputOrder, self.textCtrlInputOrder)
        self.Bind(wx.EVT_BUTTON, self.onEnterInputOrder, self.btnExec)
        self.Bind(wx.EVT_BUTTON, self.onCloseStream, self.btnStop)
        self.Bind(wx.EVT_BUTTON, self.onSendText, self.btnSendData)
        self.Bind(wx.EVT_IDLE, self.onIdle)
        self.Bind(wx.EVT_END_PROCESS, self.onProcessEnded)

    def onEnterInputOrder(self, evt):
        '''回车执行命令'''
        cmd = self.textCtrlInputOrder.GetValue().strip()
        if not cmd:
            RichMsgDialog.showOkMsgDialog(self, '命令为空', '错误')
            return
        self.process = wx.Process(self)
        self.process.Redirect()
        self.pid = wx.Execute(cmd, wx.EXEC_ASYNC, self.process)
        print(self.pid)
        self.textCtrlInputOrder.Clear() # 行为操作，每次执行完命令都清空当前命令，便于新命令的输入
        self.infoOrderResult.AppendText(f'>>> {cmd}\n')
        # self.infoOrderResult.AppendText(f'[[[BEGIN BEGIN BEGIN]]]\n')

    def onIdle(self, evt):
        '''进程数据输出到输入框'''
        if self.process is not None:
            if self.process.IsInputAvailable():
                stream = self.process.GetInputStream()
                if stream.CanRead():
                    text = stream.read()
                    self.infoOrderResult.AppendText(text)

    def onProcessEnded(self, evt):
        """进程终止时触发操作"""
        if self.process is not None:
            stream = self.process.GetInputStream()
            if stream is not None and stream.CanRead():
                text = stream.read()
                self.infoOrderResult.AppendText(text)
            self.infoOrderResult.AppendText('[[[END END END]]]\n')
            self.process.Destroy()
            self.process = None

    def onSendText(self, e):
        """向进程发送数据"""
        text = self.textCtrlInputOrder.GetValue()
        self.textCtrlInputOrder.SetValue('')
        text += '\n'
        self.process.GetOutputStream().write(text.encode('utf-8'))
        self.textCtrlInputOrder.SetFocus()

    def onCloseStream(self, evt):
        """关闭进程的输出数据流"""
        self.process.CloseOutput()

    # def __del__(self):
    #     try:
    #         self.process.Kill()
    #     except:
    #         ...
